package com.uzai.console.service.wechatprivate.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.converters.longconverter.LongStringConverter;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.uzai.common.enums.DeviceTypeEnum;
import com.uzai.common.enums.GroupSendStatusEnum;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.result.ResponseCode;
import com.uzai.console.common.ResponseMsg;
import com.uzai.console.common.utils.DateUtil;
import com.uzai.console.common.utils.Tools;
import com.uzai.console.common.utils.ZipUtils;
import com.uzai.console.config.UzaiConsoleSysConfig;
import com.uzai.console.constant.CacheKey;
import com.uzai.console.constant.Const;
import com.uzai.console.constant.ES.ESConstant;
import com.uzai.console.dto.user.wechatuser.WechatUserGroupSendMsgDto;
import com.uzai.console.dto.wechatprivate.wxcontacts.*;
import com.uzai.console.entity.DeviceWechatInfo;
import com.uzai.console.entity.GroupSendJob;
import com.uzai.console.entity.Merchant;
import com.uzai.console.entity.TbPunishOrder;
import com.uzai.console.enums.ExportInfoTypeEnum;
import com.uzai.console.enums.GroupSendJobSourceEnum;
import com.uzai.console.enums.SmsType;
import com.uzai.console.mapper.DeviceWechatInfoMapper;
import com.uzai.console.mapper.GroupSendJobMapper;
import com.uzai.console.mapper.MerchantMapper;
import com.uzai.console.service.exportinfo.ExportInfoService;
import com.uzai.console.service.wechatprivate.WxContactsGroupSendMsgService;
import com.uzai.console.service.wechatprivate.WxContactsService;
import com.uzai.console.service.wechatprivate.WxContactsSyncService;
import com.uzai.console.vo.exportinfo.ExportAmountVo;
import com.uzai.console.vo.login.LoginVo;
import com.uzai.console.vo.tb.tbpunishorder.TbPunishOrderExport;
import com.uzai.console.vo.wechatprivate.wxcontacts.WxContactsExport;
import com.uzai.console.vo.wechatprivate.wxcontacts.WxContactsInfoVo;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.tools.zip.ZipOutputStream;

/**
 * 个人微信-微信通讯录
 * @author liuqi
 * @date 2021年08月13日 11:34
 */
@Service
public class WxContactsGroupSendMsgServiceImpl implements WxContactsGroupSendMsgService {

    Logger logger = LoggerFactory.getLogger(WxContactsGroupSendMsgServiceImpl.class);

    @Autowired
    private GroupSendJobMapper groupSendJobMapper;
    @Autowired
    private WxContactsSyncService wxContactsSyncService;
    @Autowired
    private WxContactsService wxContactsService;
    @Autowired
    private ExportInfoService exportInfoService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private DeviceWechatInfoMapper deviceWechatInfoMapper;
    @Autowired
    private UzaiConsoleSysConfig uzaiConsoleSysConfig;

    /**
     * 添加群发任务
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param addBatchSendMessageTaskDto
     * @return null
     */
    public void addBatchSendMessageTask(AddBatchSendMessageTaskDto addBatchSendMessageTaskDto){

        if(true){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "此功能已经过时删除，暂时不能使用");
        }

        WxContactsQuery wxContactsQuery = addBatchSendMessageTaskDto.getWxContactsQuery();
        wxContactsQuery.setCurrent(1);//从第一页开始
        wxContactsQuery.setUserType(0); //个人微信
        wxContactsQuery.setSize(20);
        wxContactsQuery.setMerId(addBatchSendMessageTaskDto.getMerId());
        if(wxContactsQuery.getMerId() == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.PARAM_ERROR);
        }
        //获取群发消息任务内容
        WechatUserGroupSendMsgDto wechatUserGroupSendMsgDto = addBatchSendMessageTaskDto.getWechatUserGroupSendMsgDto();
        wechatUserGroupSendMsgDto.setMerId(addBatchSendMessageTaskDto.getMerId());
        if(wechatUserGroupSendMsgDto  == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.PARAM_ERROR);
        }

        if(com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(wechatUserGroupSendMsgDto.getName())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入任务名称");
        }

        if(wechatUserGroupSendMsgDto.getTimeInterval() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入发送时间间隔");
        }

        if(com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(wechatUserGroupSendMsgDto.getContent())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入消息内容");
        }

        if(wechatUserGroupSendMsgDto.getBeginTime() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入开始时间");
        }

        //查询总用户数
        Page<WxContactsInfoVo> wxContactsInfoVoPage = wxContactsService.findWxContactsList(wxContactsQuery, false);
        if(wxContactsInfoVoPage != null){
            if(wxContactsInfoVoPage.getTotal() == 0){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "查询结果为空");
            }
            Integer now = DateUtil.getNowTime();
            //添加群发消息主任务
            GroupSendJob groupSendJobParent = new GroupSendJob();
            groupSendJobParent.setId(IdWorker.getId());
            groupSendJobParent.setParentId(0L); //主任务
            groupSendJobParent.setMerId(addBatchSendMessageTaskDto.getMerId());
            groupSendJobParent.setDeviceType(DeviceTypeEnum.DT_PC_WECHAT.getKey());
            groupSendJobParent.setName(wechatUserGroupSendMsgDto.getName());
            groupSendJobParent.setSource(GroupSendJobSourceEnum.PRIVATE_CONTACTS.getId());
            groupSendJobParent.setContent(wechatUserGroupSendMsgDto.getContent());
            groupSendJobParent.setStatus(GroupSendStatusEnum.NOT_START.getValue());
            groupSendJobParent.setTotalCount((int)wxContactsInfoVoPage.getTotal());
            groupSendJobParent.setFinishCount(0);
            groupSendJobParent.setTimeInterval(wechatUserGroupSendMsgDto.getTimeInterval());
            groupSendJobParent.setBeginTime(wechatUserGroupSendMsgDto.getBeginTime());
            groupSendJobParent.setEndTime(wechatUserGroupSendMsgDto.getEndTime());
            groupSendJobParent.setExptime(now + 15*24*3600); //当前时间之后的15天内
            groupSendJobParent.setUserLab(JSONObject.toJSONString(wechatUserGroupSendMsgDto.getUserLabList()));
            groupSendJobParent.setUserRemark(wechatUserGroupSendMsgDto.getUserRemark());
            groupSendJobParent.setNightTime(wechatUserGroupSendMsgDto.getNightTime());
            groupSendJobParent.setCreateTime(now);
            groupSendJobParent.setUpdateTime(now);
            groupSendJobMapper.insertSelective(groupSendJobParent);

            try{
                //线程睡眠0.5秒
                Thread.sleep(500);
            } catch (Exception e){

            }

            //设置群发消息主任务id
            addBatchSendMessageTaskDto.setGroupSendJobParent(groupSendJobParent);

            //后台线程创建子任务和发送消息
            wxContactsSyncService.sendMessageToUserSelectedSync(addBatchSendMessageTaskDto);
        }
    }

    /**
     * 新建群发任务
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param newBatchSendMessageTaskDto
     * @return null
     */
    public void newBatchSendMessageTask(NewBatchSendMessageTaskDto newBatchSendMessageTaskDto, String loginName){

//        if(true){
//            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "活动期间，禁止群发功能");
//        }

        if(newBatchSendMessageTaskDto.getMerId() == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.PARAM_ERROR);
        }

        List<Long> deviceUniqueIdList = newBatchSendMessageTaskDto.getDeviceUniqueIdList();
        if(deviceUniqueIdList == null || deviceUniqueIdList.size() == 0){ //
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择发送消息的机器人");
        }

        if(StringUtils.isBlank(newBatchSendMessageTaskDto.getName())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入任务名称");
        }

        if(StringUtils.isBlank(newBatchSendMessageTaskDto.getContent())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入消息内容");
        }

        if(newBatchSendMessageTaskDto.getBeginTime() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入发送时间");
        }

        WxContactsQuery wxContactsQuery = new WxContactsQuery();
        wxContactsQuery.setMerId(newBatchSendMessageTaskDto.getMerId());
        wxContactsQuery.setUserType(0); //个人微信通讯录
        wxContactsQuery.setSubDeviceUniqueIdList(newBatchSendMessageTaskDto.getSubDeviceUniqueIdList());
        //免打扰时间
        Integer busyTimeInterval = newBatchSendMessageTaskDto.getBusyTimeInterval();
        //页面设置了免打扰时间(页面填写的是天数)
        if(busyTimeInterval != null){
            //免骚扰时间(针对群发消息用户过滤，这个时间发以后已经群发消息的用户不查询出来) = 现在时间-页面设置的免打扰时间
            Integer busyGroupSendMsgTime = newBatchSendMessageTaskDto.getBeginTime() - busyTimeInterval * 3600 ;
            wxContactsQuery.setBusyGroupSendMsgTime(busyGroupSendMsgTime);
        }

        //发送消息总数
        long totalCount = 0;

        //封装手机端机器人
        List<Long> deviceUniqueIdList_mobile = new ArrayList<>();

        if(newBatchSendMessageTaskDto.getGroupSendType() == 1){ //群发助手。仅支持手机端机器人

            if(newBatchSendMessageTaskDto.getTimeInterval() == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入发送间隔时间");
            }

            if(newBatchSendMessageTaskDto.getTimeInterval() < 300 || newBatchSendMessageTaskDto.getTimeInterval() > 1800 ){//间隔时间只能选择5分钟-30分钟之内
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "群发助手模式发送时间间隔必须在5分钟和30分钟之内");
            }

            for (Long deviceUniqueId : deviceUniqueIdList) {
                DeviceWechatInfo deviceWechatInfo = deviceWechatInfoMapper.selectById(deviceUniqueId, newBatchSendMessageTaskDto.getMerId());
                if(deviceWechatInfo != null && Tools.getInteger(deviceWechatInfo.getRecvmsgType()).intValue() == 1){//手机端
                    //添加手机端机器人列表中
                    deviceUniqueIdList_mobile.add(deviceUniqueId);
                    //查询微信通讯录总数
                    wxContactsQuery.setDeviceUniqueId(deviceUniqueId);
                    //单个机器人查询总数
                    long totalCount_device = wxContactsService.searchTotal(wxContactsQuery);
                    if(totalCount_device >= ESConstant.TOTAL_MAX) { //大于2万条，不支持群发
                        throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该机器人下的通讯录成员总数超过2万个，机器人id=：" + deviceUniqueId);
                    }
                    totalCount = totalCount + totalCount_device;
                }
            }

            if(deviceUniqueIdList_mobile.size() == 0){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "未找到手机端在线机器人");
            }

            //重置手机端机器人
            newBatchSendMessageTaskDto.setDeviceUniqueIdList(deviceUniqueIdList_mobile);
        }else{//普通发送
            if(newBatchSendMessageTaskDto.getTimeInterval() == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入发送时间间隔");
            }
            for (Long deviceUniqueId : deviceUniqueIdList) {
                DeviceWechatInfo deviceWechatInfo = deviceWechatInfoMapper.selectById(deviceUniqueId, newBatchSendMessageTaskDto.getMerId());
                    //查询微信通讯录总数
                    wxContactsQuery.setDeviceUniqueId(deviceUniqueId);
                    //单个机器人查询总数
                    long totalCount_device = wxContactsService.searchTotal(wxContactsQuery);
                    if(totalCount_device >= ESConstant.TOTAL_MAX) { //大于2万条，不支持群发
                        throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该机器人下的通讯录成员总数超过2万个，机器人id=：" + deviceUniqueId);
                    }
                    totalCount = totalCount + totalCount_device;
            }
        }

        //发送消息总数
        if(totalCount == 0){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "选择的机器人没有通讯录好友");
        }

        Integer now = DateUtil.getNowTime();
        //添加群发消息主任务
        GroupSendJob groupSendJobParent = new GroupSendJob();
        groupSendJobParent.setId(IdWorker.getId());
        groupSendJobParent.setParentId(0L); //主任务
        groupSendJobParent.setMerId(newBatchSendMessageTaskDto.getMerId());
        groupSendJobParent.setDeviceType(DeviceTypeEnum.DT_PC_WECHAT.getKey());
        //任务名称
        String name = Tools.getStr(newBatchSendMessageTaskDto.getName());

        name = name.replace("[创建时间]", Tools.getDateFormat(new Date(now * 1000L), "yyMMdd"))
                .replace("[创建账号]", Tools.getStr(loginName));

        if(deviceUniqueIdList.size() == 1){//需要过滤参数
            DeviceWechatInfo deviceWechatInfo = deviceWechatInfoMapper.selectById(deviceUniqueIdList.get(0), newBatchSendMessageTaskDto.getMerId());
            if(deviceWechatInfo == null){
                throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "选择的机器人不存在");
            }
            name = name.replace("[机器人昵称]", Tools.getStr(deviceWechatInfo.getDeviceName()))
                    .replace("[机器人备注]",Tools.getStr(deviceWechatInfo.getDeviceRemark()));
        }

        groupSendJobParent.setName(name);
        groupSendJobParent.setSource(GroupSendJobSourceEnum.PRIVATE_CONTACTS.getId());
        groupSendJobParent.setContent(newBatchSendMessageTaskDto.getContent());
        groupSendJobParent.setStatus(GroupSendStatusEnum.INIT.getValue());
        //groupSendJobParent.setTotalCount((int)totalCount); //预计发送总数
        groupSendJobParent.setTotalCount(0); //默认为0
        groupSendJobParent.setFinishCount(0);
        groupSendJobParent.setTimeIntervalMin(newBatchSendMessageTaskDto.getTimeIntervalMin());
        groupSendJobParent.setTimeInterval(newBatchSendMessageTaskDto.getTimeInterval());
        groupSendJobParent.setBeginTime(newBatchSendMessageTaskDto.getBeginTime());
        groupSendJobParent.setEndTime(newBatchSendMessageTaskDto.getEndTime());
        groupSendJobParent.setExptime(now + 15*24*3600); //当前时间之后的15天内
        groupSendJobParent.setUserRemark(newBatchSendMessageTaskDto.getUserRemark());
        groupSendJobParent.setUserLab(Tools.getStrNull(JSONObject.toJSONString(newBatchSendMessageTaskDto.getUserLabList())));
        groupSendJobParent.setCleanLab(newBatchSendMessageTaskDto.getCleanLab());
        groupSendJobParent.setUserTags(Tools.getStrNull(JSONObject.toJSONString(newBatchSendMessageTaskDto.getUserTagsList())));
        groupSendJobParent.setNightTime(newBatchSendMessageTaskDto.getNightTime());
        groupSendJobParent.setCreateTime(now);
        groupSendJobParent.setUpdateTime(now);
        groupSendJobParent.setBusyTimeInterval(newBatchSendMessageTaskDto.getBusyTimeInterval());
        groupSendJobParent.setIgnoreName(Tools.getStrEmpty(JSONObject.toJSONString(newBatchSendMessageTaskDto.getIgnoreNameList())));
        groupSendJobParent.setIgnoreRemark(Tools.getStrEmpty(JSONObject.toJSONString(newBatchSendMessageTaskDto.getIgnoreRemarkList())));
        groupSendJobParent.setSendStartTime(newBatchSendMessageTaskDto.getBeginTime());
        groupSendJobParent.setGroupSendType(newBatchSendMessageTaskDto.getGroupSendType());//赋值群发消息类型
        groupSendJobParent.setUserQueryPara(Tools.getStrNull(JSONObject.toJSONString(newBatchSendMessageTaskDto.getGroupSendJobUserQueryParaDto())));
        groupSendJobParent.setParaQueryType(Tools.getInteger(newBatchSendMessageTaskDto.getParaQueryType()));
        groupSendJobMapper.insertSelective(groupSendJobParent);

        //后台异步线程创建子任务和群发消息
        wxContactsSyncService.newBatchSendMessageTaskSync(newBatchSendMessageTaskDto, groupSendJobParent.getId(), loginName);
    }

    /**
     * 查询通讯结果导出数据
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param exportResultDto
     * @return null
     */
    public void exportByQeuryResult(ExportResultDto exportResultDto){

        if(exportResultDto.getMerId() == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.PARAM_ERROR);
        }

        if(StringUtils.isBlank(exportResultDto.getCode())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入验证码");
        }

        Merchant merchant = merchantMapper.selectById(exportResultDto.getMerId());
        if(merchant == null ){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "运营商不存在");
        }

        //如果输入的验证码不是系统通用密码，则需要验证
        if(!uzaiConsoleSysConfig.getDefaultPassword().equals(exportResultDto.getCode())){
            //获取存在redis中的验证码
            String codeByRedis = (String) redisTemplate.opsForValue().get(String.format(SmsType.SPECIAL_OPERATE.getDesc(), merchant.getMobile()));
            //判断验证码是否过期
            if (StringUtils.isBlank(codeByRedis)){
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.CODE_MISS);
            }

            //验证码是否正确
            if (!codeByRedis.equals(exportResultDto.getCode())){
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, ResponseMsg.CODE_ERR);
            }

            //验证成功，删除验证码
            redisTemplate.delete(String.format(SmsType.SPECIAL_OPERATE.getDesc(), merchant.getMobile()));
        }

        WxContactsQuery wxContactsQuery = exportResultDto.getWxContactsQuery();
        wxContactsQuery.setMerId(exportResultDto.getMerId());
        wxContactsQuery.setUserType(0); //个人微信通讯录

        //机器人列表
        List<Long> deviceUniqueIdList = wxContactsQuery.getDeviceUniqueIdList();
        if(deviceUniqueIdList == null && deviceUniqueIdList.size() == 0){
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请选择机器人");
        }

        //计算费用
        ExportAmountVo exportAmountVo = wxContactsService.getExportAmount(wxContactsQuery);

        //生成ZIP文件流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream out = new ZipOutputStream(outputStream);

        //查询总数
        for (Long deviceUniqueId : deviceUniqueIdList) {
            //导出excel文件序号
            long exportFileNumber = deviceUniqueId.longValue();
            //分页查询（每页10条）
            //执行分页查询对象
            wxContactsQuery.setSize(100);
            int currentPage = 1;
            wxContactsQuery.setCurrent(currentPage);
            wxContactsQuery.setDeviceUniqueIdList(null);
            wxContactsQuery.setDeviceUniqueId(deviceUniqueId);

            //存放导出文件对象(一个机器人一个表格)
            List<WxContactsExport> wxContactsExportList = new ArrayList<>();

            Page<WxContactsInfoVo> wxContactsInfoVoList = wxContactsService.findWxContactsList(wxContactsQuery,false);
            while(wxContactsInfoVoList != null && wxContactsInfoVoList.getRecords() != null && wxContactsInfoVoList.getRecords().size() > 0){
                for(WxContactsInfoVo wxContactsInfoVo : wxContactsInfoVoList.getRecords()){
                    WxContactsExport wxContactsExport = new WxContactsExport();
                    BeanUtils.copyProperties(wxContactsInfoVo, wxContactsExport);
                    wxContactsExportList.add(wxContactsExport);
                }

                //循环查询下一页
                currentPage ++ ;
                wxContactsQuery.setCurrent(currentPage);
                wxContactsInfoVoList = wxContactsService.findWxContactsList(wxContactsQuery,false);
            }

            ByteArrayOutputStream byteArrayOutputStream = null;
            try {
                String fileName = "个人微信通讯录_" + exportFileNumber +".xlsx";
                //创建流
                byteArrayOutputStream = new ByteArrayOutputStream();
                //打包成ZIP文件
                EasyExcel.write(byteArrayOutputStream, WxContactsExport.class).registerConverter(new LongStringConverter()).sheet("个人微信通讯录").doWrite(wxContactsExportList);
                ZipUtils.zip(out, new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), fileName);
                byteArrayOutputStream.close();
                //清空本次导出的数据列表
                wxContactsExportList.clear();
            }catch (Exception e){
                if(byteArrayOutputStream != null){
                    try {
                        byteArrayOutputStream.close();
                    } catch (IOException ex) {
                        logger.error(ex.getMessage(), ex);
                    }
                }
                logger.error("----导出个人微信通讯录异常--error={}", e.getMessage());
            }
        }

        try {
            // 注意关闭流的顺序，在上传oss之前必须关闭流否则下载解压的时候会报“文件末端错误”的问题
            outputStream.close();
            out.close();
        }catch (Exception e){
            logger.error("----导出个人微信通讯录异常--error={}", e.getMessage());
        }finally {

        }

        InputStream byteArrayInputStream = new ByteArrayInputStream(outputStream.toByteArray());
        String zipFileName = "个人微信通讯录_" + System.currentTimeMillis() + ".zip";
        //上传文件通讯录
        exportInfoService.uploadExportFile(byteArrayInputStream, exportResultDto.getMerId(), zipFileName, exportAmountVo, ExportInfoTypeEnum.EXPORT_INFO_WXCONTACTS.getId());

    }




}
